package com.xbongbong.paas.service.dynamic.crm.strategy.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.log.constant.CrmLogMemoConstant;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.service.dynamic.crm.strategy.AbstractDynamicStrategy;
import com.xbongbong.paas.service.dynamic.crm.strategy.PaymentSheetDynamicStrategy;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.customercommunicate.pojo.dto.DynamicDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicDeleteDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicPaymentSheetDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicRefInfoDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicSaveDTO;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 *回款
 *
 *@author weijianxun
 */
@Service("paymentSheetDynamicStrategyImpl")
public class PaymentSheetDynamicStrategyImpl extends AbstractDynamicStrategy implements PaymentSheetDynamicStrategy {

    private final Logger LOG = LoggerFactory.getLogger(PaymentSheetDynamicStrategyImpl.class);

    private static final Map<String, Integer> refTextToLogTypeMap = new HashMap<>();

    static {
        refTextToLogTypeMap.put(PaymentSheetEnum.CUSTOMER_ID.getAttr(), ProjectLogEnum.CUSTOMER_REF.getSubType());
        refTextToLogTypeMap.put(PaymentSheetEnum.CONTRACT.getAttr(), ProjectLogEnum.CONTRACT_REF.getSubType());
    }

    public static Map<String, Integer> getRefTextToLogTypeMap(){
        return Collections.unmodifiableMap(refTextToLogTypeMap);
    }

    @Override
    public List<Integer> type() {
        return Arrays.asList(
                XbbRefTypeEnum.PAYMENT_SHEET.getCode(),
                XbbRefTypeEnum.WRITE_OFF_PREPAYMENT.getCode(),
                XbbRefTypeEnum.PREPAYMENT.getCode(),
                XbbRefTypeEnum.RED_PREPAYMENT.getCode(),
                XbbRefTypeEnum.RED_PAYMENT_SHEET.getCode(),
                XbbRefTypeEnum.RED_WRITE_OFF_PREPAYMENT.getCode(),
                XbbRefTypeEnum.RED_WRITE_OFF_BALANCE.getCode(),
                XbbRefTypeEnum.BAD_DEBT.getCode()
        );
    }


    @Override
    @Async("dynamicThreadPool")
    public void writeOff(DynamicPaymentSheetDTO dynamicPaymentSheetDTO) {
        try {
            creatDynamic(dynamicPaymentSheetDTO, CrmLogMemoConstant.DYNAMIC_USER_PAYMENT_SHEET_ADD_CONTRACT);
            // creatDynamic(dynamicPaymentSheetDTO, CustomerCommunicateConstant.PAYMENT_SHEET_ADD_CONTRACT);
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.PaymentSheetDynamicStrategyImpl.writeOff", e);
        }
    }

    @Override
    @Async("dynamicThreadPool")
    public void prepayment(DynamicPaymentSheetDTO dynamicPaymentSheetDTO) {
        try {
            SaasFormSaveDTO saasFormSaveDTO = dynamicPaymentSheetDTO.getSaasFormSaveDTO();
            PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
            Integer businessType = saasFormSaveDTO.getBusinessType();
            PaymentSheetTypeEnum paymentSheetTypeEnum = PaymentSheetTypeEnum.getByBusinessType(businessType);
            SheetTypeEnum sheetTypeEnum = paymentSheetTypeEnum.getSheetTypeEnum();
            JSONObject data = newPaasFormDataEntity.getData();
            UserEntity creator = dynamicPaymentSheetDTO.getCreator();
            boolean redFlag = false;
            if (Objects.equals(sheetTypeEnum, SheetTypeEnum.RED_PREPAYMENT)) {
                redFlag = true;
            }
            String logMemo;
            if (redFlag) {
                logMemo = CrmLogMemoConstant.DYNAMIC_USER_PAYMENT_SHEET_RED_PREPAYMENT_ADD;
            } else {
                logMemo = CrmLogMemoConstant.DYNAMIC_USER_PAYMENT_SHEET_PREPAYMENT_ADD;
            }
            String customerTitle = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getName();
            if (Objects.equals(saasFormSaveDTO.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR.getCode())) {
                customerTitle = XbbRefTypeEnum.DISTRIBUTOR_MANAGEMENT.getName();
            }
            String customerName = data.getString(PaymentSheetEnum.CUSTOMER_NAME_LINK_TEXT.getAttr());

            DynamicSaveDTO dynamicSaveDTO = DynamicSaveDTO.initDynamicSaveDTO(newPaasFormDataEntity.getId(), null, saasFormSaveDTO, creator, null);
            saveRefUpDynamic(dynamicSaveDTO, refTextToLogTypeMap, null,
                    DynamicRefInfoDTO.initDynamicRefInfoDTO(newPaasFormDataEntity.getId(), XbbRefTypeEnum.PAYMENT_SHEET.getCode(), newPaasFormDataEntity.getSerialNo()), logMemo, DynamicDTO.initMemoHolder(customerTitle, customerName, newPaasFormDataEntity.getSerialNo()), ProjectLogEnum.PAYMENT_CREATE.getSubType());
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.PaymentSheetDynamicStrategyImpl.prepayment", e);
        }
    }

    @Override
    @Async("dynamicThreadPool")
    public void red(DynamicPaymentSheetDTO dynamicPaymentSheetDTO) {
        try {
            creatDynamic(dynamicPaymentSheetDTO, CrmLogMemoConstant.DYNAMIC_USER_PAYMENT_SHEET_RED_ADD_CONTRACT);
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.PaymentSheetDynamicStrategyImpl.red", e);
        }
    }

    @Override
    @Async("dynamicThreadPool")
    public void bad(DynamicPaymentSheetDTO dynamicPaymentSheetDTO) {
        try {
            creatDynamic(dynamicPaymentSheetDTO, CrmLogMemoConstant.DYNAMIC_USER_PAYMENT_SHEET_BAD_CONTRACT);
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.PaymentSheetDynamicStrategyImpl.bad", e);
        }
    }


    @Override
    @Async("dynamicThreadPool")
    public void batchDelete(DynamicDeleteDTO dynamicDeleteDTO) {
        try {
            super.batchRefSaveUpDynamicByDeleteBatch(dynamicDeleteDTO, refTextToLogTypeMap, null, PaymentSheetEnum.SHEET_NO.getAttr(), ProjectLogEnum.PAYMENT_DELETE.getSubType());
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.PaymentSheetDynamicStrategyImpl.batchDelete", e);
        }
    }

    private void creatDynamic(DynamicPaymentSheetDTO dynamicPaymentSheetDTO, String logMemo) throws XbbException {
        SaasFormSaveDTO saasFormSaveDTO = dynamicPaymentSheetDTO.getSaasFormSaveDTO();
        UserEntity creator = dynamicPaymentSheetDTO.getCreator();
        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        JSONObject data = newPaasFormDataEntity.getData();
        String contractTitle = XbbRefTypeEnum.CONTRACT.getName();
        if (Objects.equals(saasFormSaveDTO.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR.getCode())) {
            contractTitle = XbbRefTypeEnum.ORDER.getName();
        }
        JSONArray contractNoArr = data.getJSONArray(PaymentSheetEnum.CONTRACT_LINK_TEXT.getAttr());
        List<String> contractNoList = contractNoArr == null ? new ArrayList<>() : contractNoArr.toJavaList(String.class);
        //逗号分隔的合同编号字符串
        String contractNos = String.join(SymbolConstant.COMMA_ENGLISH, contractNoList);
        DynamicSaveDTO dynamicSaveDTO = DynamicSaveDTO.initDynamicSaveDTO(newPaasFormDataEntity.getId(), null, saasFormSaveDTO, creator, null);
        saveRefUpDynamic(dynamicSaveDTO, refTextToLogTypeMap, null,
                DynamicRefInfoDTO.initDynamicRefInfoDTO(newPaasFormDataEntity.getId(), XbbRefTypeEnum.PAYMENT_SHEET.getCode(), newPaasFormDataEntity.getSerialNo()), logMemo, DynamicDTO.initMemoHolder(contractTitle, contractNos, newPaasFormDataEntity.getSerialNo()), ProjectLogEnum.PAYMENT_CREATE.getSubType());

    }
}
